home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / text / misc / mpage.lha / mpage / mpage.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-25  |  9.8 KB  |  326 lines

  1. /*
  2.  * mpage.c
  3.  */
  4.  
  5. /*
  6.  * mpage:    a program to reduce pages of print so that several pages
  7.  *           of output appear on one printed page.
  8.  *
  9.  * Copyright (c) 1988 Mark P. Hahn, Herndon, Virginia
  10.  * Copyright (c) 1994-1997 Marcel J.E. Mol, The Netherlands
  11.  *                    marcel@mesa.nl
  12.  
  13.  * Written by:
  14.  *   ...!uunet!\                       Mark Hahn, Sr Systems Engineer
  15.  *              >pyrdc!mark            Pyramid Technology Corporation
  16.  * ...!pyramid!/                       Vienna, Va    (703)848-2050
  17.  *
  18.  *  
  19.  *     Permission is granted to anyone to make or distribute verbatim
  20.  *     copies of this document as received, in any medium, provided
  21.  *     that this copyright notice is preserved, and that the
  22.  *     distributor grants the recipient permission for further
  23.  *     redistribution as permitted by this notice.
  24.  *
  25.  */
  26.  
  27. #include "mpage.h"
  28. #include <string.h>
  29. #include <time.h>
  30. #include <fcntl.h>
  31.  
  32. #include "encoding.h"
  33.  
  34. /*
  35.  * Function Declarations
  36.  */
  37. static void ps_title();
  38.  
  39.  
  40.  
  41. int
  42. main(argc, argv)
  43. int argc;
  44. char **argv;
  45. {
  46.     FILE *outfd;
  47.     int currarg;
  48.     struct sheet *thelist;
  49.     struct sheet *thesheet;
  50.     char outcommand[LINESIZE]; /* the command which is the output filter */
  51.  
  52.  
  53. #ifdef OS2
  54.     /*
  55.      * wildcard expansion from emx package
  56.      */
  57.     _wildcard (&argc, &argv);
  58. #endif
  59.  
  60.     /*
  61.      * examine the environment for PRINTER (or LPDEST) and MPAGE
  62.      * environment variables
  63.      */
  64.     if ((currarg = do_env()) < 0) {
  65.         usage(currarg);
  66.         exit(1);
  67.     }
  68.         
  69.     if ((currarg = do_args(argc, argv, 0)) < 0) {
  70.         usage(currarg);
  71.         exit(1);
  72.     }
  73.  
  74.     /*
  75.      * if a print queue was specified then create a print command using
  76.      * the queue, else use standard output.
  77.      */
  78.     if (doprint) {
  79.         if (printque != NULL)
  80.             (void) sprintf(outcommand, "%s %s%s",
  81.                            printprog, printarg, printque);
  82.         else
  83.             (void) strcpy(outcommand, printprog);
  84.         if ((outfd = popen(outcommand, "w")) == NULL) {
  85.             fprintf(stderr, "%s: cannot create pipe for '%s'\n",
  86.                             MPAGE, outcommand);
  87.             perror(MPAGE);
  88.         }
  89.     }
  90.     else
  91.         outfd = stdout;
  92.  
  93.     /*
  94.      * pick the array of sheet lists based upon the specified option
  95.      */
  96.     if (sheetorder == UPDOWN)
  97.         sheetlist = up_down;
  98.     else
  99.         sheetlist = left_right;
  100.  
  101.     /*
  102.      * from the array of sheet lists pick the proper sheet list for
  103.      * the given sheetaspect, then select the proper sheet format
  104.      * for the given number of redueced pages per output page
  105.      */
  106.     thelist = sheetlist[sheetaspect];
  107.     thesheet = &(thelist[sheetindex]);
  108.  
  109.     /* GPN. */
  110.     if (Coli == 1)
  111.         thesheet = &(coli[0]);
  112.     if (Coli == 2)
  113.         thesheet = &(coli[1]);
  114.  
  115.     orientation = (sheetindex + sheetaspect) & 0x01;
  116.  
  117.     /*
  118.      * if either lines or columns were specified as options, over
  119.      * the default sheets idea of the number of line or columns
  120.      * per reduced page
  121.      */
  122.     if (opt_lines > 0)
  123.         thesheet->sh_plength = opt_lines;
  124.     if (opt_width > 0)
  125.         thesheet->sh_cwidth = opt_width;
  126.  
  127.     /*
  128.      * Prepare the textbox parameters when needed
  129.      */
  130.     if (opt_textbox) {
  131.         textbox.over = textmargin_left;
  132.         textbox.lift = textmargin_bottom;
  133.         textbox.wide = thesheet->sh_cwidth  - (textmargin_left+textmargin_right);
  134.         textbox.high = thesheet->sh_plength - (textmargin_top+textmargin_bottom);
  135.     }
  136.  
  137.     /*
  138.      * if there are arguments left over after processing options, then
  139.      * these are names of files to process, else process the standard
  140.      * input
  141.      */
  142.     if (currarg < argc) {
  143.         ps_title(argv[currarg], outfd);
  144.         for ( ; currarg < argc; currarg++)
  145.             do_file(argv[currarg], thesheet, outfd);
  146.     }
  147.     else {
  148.         ps_title("<stdin>", outfd);
  149.         do_stdin(thesheet, outfd);
  150.     }
  151.  
  152.     /*
  153.      * in case files are merged on sheets, make sure the last page
  154.      * is printed...
  155.      */
  156.     if (points->pp_origin_x != 0 && !opt_file) {
  157.         if (had_ps)
  158.             fprintf(outfd, "showsheet\n");
  159.         else {
  160.             fprintf(outfd, "restore\n");
  161.             fprintf(outfd, "showpage\n");
  162.         }
  163.     }
  164.  
  165.     /*
  166.      * having processed all input, print out a PS trailer
  167.      * (timing stuff stolen from old adobe troff stuff)
  168.      */
  169.     fprintf(outfd, "%%%%Trailer\n");
  170.     if (opt_verbose) {
  171.         /*
  172.         ps_pagenum++;
  173.         fprintf(outfd, "%%%%Page: %d %d\n", ps_pagenum, ps_pagenum);
  174.         */
  175.         fprintf(outfd, "statusdict begin jobname print flush");
  176.         fprintf(outfd, " (: Job finished:\\n) print\n");
  177.         fprintf(outfd, "(\\tmpage time (s) = ) print flush usertime ");
  178.         fprintf(outfd, "mp_stm sub 1000 div ==\n(\\tmpage pages = ) print");
  179.         fprintf(outfd, " flush pagecount mp_pgc sub ==\nend flush\n");
  180.         /* fprintf(outfd, "showpage\n"); */
  181.     }
  182.     fprintf(outfd, "%%%%Pages: %d\n", ps_pagenum);
  183.     if (opt_verbose) {
  184.         fprintf(stderr, "[%s: %d pages, ", MPAGE, ps_pagenum);
  185.         if (doprint) {
  186.             if (printque != NULL)
  187.                 fprintf(stderr, "print queue %s]\n", printque);
  188.             else
  189.                 fprintf(stderr, "on default printer queue]\n");
  190.         }
  191.         else
  192.             fprintf(stderr, "on <stdout>]\n");
  193.     }
  194.     /*
  195.      * proper clean up to make sure the pipe is flushed
  196.      */
  197.     if (doprint)
  198.         (void) pclose(outfd);
  199.  
  200.     return 0;
  201.  
  202. } /* main */
  203.  
  204.  
  205.  
  206. /*
  207.  * ps_title prints a post script header suitable for PS processors
  208.  */
  209. static void
  210. ps_title(name, outfd)
  211.  char *name;
  212.  FILE *outfd;
  213. {
  214.     time_t curr_time;
  215.     char *time_str;
  216.     FILE * charfp;
  217.     char buf[LINESIZE];
  218.  
  219.     fprintf(outfd, "%%!PS-Adobe-2.0\n");
  220.     fprintf(outfd, "%%%%DocumentFonts: %s Times-Bold\n", fontname);
  221.     fprintf(outfd, "%%%%Title: %s (%s)\n", name, MPAGE);
  222.     fprintf(outfd, "%%%%Creator: %s %s\n", MPAGE, VERSION);
  223.     (void) time(&curr_time);
  224.     time_str = ctime(&curr_time);
  225.     fprintf(outfd, "%%%%CreationDate: %s", time_str);
  226.     fprintf(outfd, "%%%%Orientation: %s\n", orientation ? "Landscape" : "Portrait");
  227.     fprintf(outfd, "%%%%DocumentMedia: %s %d %d\n", media, ps_width, ps_height);
  228.     fprintf(outfd, "%%%%BoundingBox: %d %d %d %d\n",
  229.                    sheetmargin_left, sheetmargin_bottom,
  230.                    ps_width - sheetmargin_right,
  231.                    ps_height - sheetmargin_top);
  232.     fprintf(outfd, "%%%%Pages: (atend)\n");
  233.     fprintf(outfd, "%%%%EndComments\n\n");
  234.     fprintf(outfd, "%%%%BeginProlog\n\n");
  235.     fprintf(outfd, "/mp_stm usertime def\n");
  236.     fprintf(outfd, "/mp_pgc statusdict begin pagecount end def\n");
  237.     fprintf(outfd, "statusdict begin /jobname (%s) def end\n", name);
  238.     if (opt_duplex) {
  239.        fprintf(outfd, "statusdict /setduplexmode known");
  240.        fprintf(outfd, " { statusdict begin true setduplexmode end } if\n");
  241.        if (opt_tumble) {
  242.            fprintf(outfd, "statusdict /settumble known ");
  243.            fprintf(outfd, "{ statusdict begin true settumble end } if\n"); 
  244.        }
  245.     }
  246.     if (opt_encoding) {
  247.         fprintf(outfd,
  248.                 "/reencsmalldict 12 dict def "
  249.                 "/ReEncodeSmall { reencsmalldict begin\n"
  250.                 "/newcodesandnames exch def "
  251.                 "/newfontname exch def "
  252.                 "/basefontname exch def\n"
  253.                 "/basefontdict basefontname findfont def "
  254.                 "/newfont basefontdict maxlength dict def\n"
  255.                 "basefontdict "
  256.                 "{ exch dup /FID ne "
  257.                   "{ dup /Encoding eq "
  258.                     "{ exch dup length array copy newfont 3 1 roll put } "
  259.                     "{ exch newfont 3 1 roll put }\n"
  260.                     "ifelse }\n"
  261.                 "  { pop pop }\n"
  262.                 "  ifelse } "
  263.                 "forall\n"
  264.                 "newfont /FontName newfontname put\n"
  265.                 "newcodesandnames aload pop "
  266.                 "newcodesandnames length 2 idiv\n"
  267.                 "{ newfont /Encoding get 3 1 roll put } "
  268.                 "repeat\n"
  269.                 "newfontname newfont definefont pop "
  270.                 "end } def\n");
  271.  
  272.         fprintf(outfd, "/charvec [\n");
  273.  
  274.         if (charvec_file != NULL) {
  275.             if ((charfp = fopen(charvec_file, "r")) == NULL) {
  276.                 perror(charvec_file);
  277.                 exit(1);
  278.             }
  279.             while (fgets(buf, LINESIZE, charfp) != NULL) {
  280.                 if (*buf != '%' && *buf != '\n')
  281.                     if (first_encoding == -1) {
  282.                         first_encoding = atoi(buf);
  283.                         last_encoding = atoi(strchr(buf, ' '));
  284. # ifdef DEBUG
  285.                         fprintf(stderr, "first=%d, last=%d\n",
  286.                                         first_encoding, last_encoding);
  287. #endif
  288.                     }
  289.                     else
  290.                         fprintf(outfd, "%s", buf);
  291.             }
  292.         }
  293.         else { /* use internal default encoding */
  294.             int i;
  295.  
  296.             first_encoding = encoding_table_first;
  297.             last_encoding  = encoding_table_last;
  298.             for (i = 0; i <= last_encoding - first_encoding; i++)
  299.                 fprintf(outfd, "%s\n", encoding_table[i]);
  300.         }
  301.         fprintf(outfd, "] def\n");
  302.         fprintf(outfd, "/%s /OurCharSet charvec ReEncodeSmall\n", fontname);
  303.     }
  304.     else {
  305.         first_encoding = ' ';
  306.         last_encoding = '~';
  307.     }
  308.  
  309.     fprintf(outfd, "/textfont /%s findfont %d scalefont def\n",
  310.                    opt_encoding ? "OurCharSet" : fontname, fsize - 1);
  311.     fprintf(outfd, "/fnamefont /Times-Bold findfont %d scalefont def\n", HSIZE);
  312.     fprintf(outfd, "/headerfont /Times-Bold findfont %d scalefont def\n",
  313.                    HSIZE - 2);
  314.     fprintf(outfd, "textfont setfont\n");
  315.     fprintf(outfd, "(a) stringwidth pop /mp_a_x exch def\n");
  316. # ifdef DEBUG
  317.     if (Debug_flag & DB_PSMPAGE)
  318.         fprintf(outfd, "(\\t'a' length ) print mp_a_x ==\nflush\n");
  319. # endif
  320.     fprintf(outfd, "%%%%EndProlog\n");
  321.  
  322.     return;
  323.  
  324. } /* ps_title */
  325.  
  326.